package org.example.onlinejudge.service;

import org.example.onlinejudge.model.Permission;
import org.example.onlinejudge.model.Role;
import org.example.onlinejudge.model.User;
import org.example.onlinejudge.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashSet;
import java.util.Set;

/**
 * 自定义UserDetailsService实现
 * 负责为Spring Security提供用户认证信息
 * 实现逻辑：
 * 1. 实现UserDetailsService接口，提供loadUserByUsername方法
 * 2. 从数据库查询用户信息（包含角色和权限）
 * 3. 构建Spring Security的权限集合，包括角色和具体权限
 * 4. 角色添加ROLE_前缀以符合Spring Security规范
 * 5. 将用户信息转换为UserDetails对象供Spring Security使用
 */
@Service
public class CustomUserDetailsService implements UserDetailsService {

    @Autowired
    private UserRepository userRepository;

    @Override
    @Transactional(readOnly = true)
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        // 从数据库查询用户（包含角色和权限信息）
        User user = userRepository.findByUsernameWithRoles(username)
                .orElseThrow(() -> new UsernameNotFoundException("用户不存在: " + username));

        // 构建权限列表
        Set<GrantedAuthority> authorities = new HashSet<>();

        // 添加角色及角色权限
        for (Role role : user.getRoles()) {
            // 添加角色（Spring Security规定角色需要ROLE_前缀）
            authorities.add(new SimpleGrantedAuthority("ROLE_" + role.getRoleCode()));

            // 添加该角色的所有权限
            for (Permission permission : role.getPermissions()) {
                authorities.add(new SimpleGrantedAuthority(permission.getPermCode()));
            }
        }

        // 添加用户的直接权限（不通过角色）
        for (Permission permission : user.getPermissions()) {
            authorities.add(new SimpleGrantedAuthority(permission.getPermCode()));
        }

        // 返回Spring Security的UserDetails对象
        return org.springframework.security.core.userdetails.User
                .withUsername(user.getUsername())
                .password(user.getPassword())
                .authorities(authorities)
                .accountExpired(false)
                .accountLocked(false)
                .credentialsExpired(false)
                .disabled(!user.getEnabled())
                .build();
    }

    /**
     * 根据用户名获取用户实体（包含完整信息）
     */
    @Transactional(readOnly = true)
    public User getUserByUsername(String username) {
        return userRepository.findByUsernameWithRoles(username)
                .orElseThrow(() -> new UsernameNotFoundException("用户不存在: " + username));
    }
}


